package com.lenovo.tool;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class TranslationMerge {
	private Map<String, String> map;

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		if (args.length != 1) {
			System.out.println("please enter the config file name");
			return;
		}

		File configFile = new File(args[0]);
		if (!configFile.exists() || !configFile.isFile()) {
			System.out.println("config file error");
			return;
		}

		TranslationMerge merge = new TranslationMerge();
		merge.mergeFiles(configFile);
	}

	private void mergeFiles(File configFile) {
		try {
			Document doc = DocumentUtils.openDocument(configFile);
			String basedirStr = doc.getElementsByTagName("basedir").item(0)
					.getTextContent().trim();
			if (basedirStr.length() == 0) {
				System.out.println("basedir is null");
				return;
			}
			File basedir = new File(basedirStr);
			if (!basedir.isDirectory()) {
				System.out.println("basedir is not a directionary");
				return;
			}
			initRule(doc);
			doAction(basedir);
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		}
	}

	private void initRule(Document doc) {
		NodeList nodes;
		Element item;

		map = new HashMap<String, String>();
		nodes = ((Element)doc.getElementsByTagName("strings").item(0)).getChildNodes();
		for (int i = 0; i < nodes.getLength(); i++) {
			if(nodes.item(i) instanceof Element) {
				item = (Element) nodes.item(i);
				map.put(item.getTextContent(), item.getAttribute("target"));
			}
		}

		nodes = ((Element)doc.getElementsByTagName("arrays").item(0)).getChildNodes();
		for (int i = 0; i < nodes.getLength(); i++) {
			if(nodes.item(i) instanceof Element) {
				item = (Element) nodes.item(i);
				map.put(item.getTextContent(), item.getAttribute("target"));
			}
		}
	}

	private void doAction(File basedir) {
		File[] files = basedir.listFiles();
		String src;
		String target;
		for (File file : files) {
			if (file.isDirectory()) {
				doAction(file);
			} else {
				src = file.getAbsolutePath().replace('\\', '/');
				src = src.substring(src.lastIndexOf('/') + 1);
				target = map.get(src);
				if (target != null) {
					merge(file, new File(file.getParent(), target));
				}
			}
		}
	}

	private void merge(File src, File target) {
		if (!target.exists()) {
			src.renameTo(target);
			return;
		}
		String line;
		BufferedReader reader = null;
		PrintWriter writer = null;
		File temp = new File(src.getParent(), ".temp"
				+ System.currentTimeMillis());
		try {
			writer = new PrintWriter(temp);
			reader = new BufferedReader(new FileReader(target));
			while ((line = reader.readLine()) != null) {
				if (line.contains("</resources>")) {
					line = line.substring(0, line.indexOf("</resources>"));
					if (line.length() > 0) {
						writer.println(line);
					}
					break;
				} else {
					writer.println(line);
				}
			}
			writer.flush();
			reader.close();
			reader = null;

			Document doc = DocumentUtils.openDocument(src);
			List<Element> items = new ArrayList<Element>();
			NodeList nodes = ((Element) doc.getElementsByTagName("resources")
					.item(0)).getChildNodes();
			Element node;
			for (int i = 0; i < nodes.getLength(); i++) {
				if(nodes.item(i) instanceof Element) {
					node = (Element) nodes.item(i);
					items.add(node);
				}
			}

			writer.println("\n\t<!-- begin,merge from " + src.getName()
					+ " -->");
			for (Element element : items) {
				writer.println("\t" + node2Str(element));
				System.out.println(node2Str(element));
			}
			writer.println("\t<!-- end,merge from " + src.getName() + " -->");
			writer.println("</resources>");
			writer.flush();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		} finally {
			if (reader != null) {
				try {
					reader.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (writer != null) {
				writer.close();
			}
			src.delete();
			target.delete();
			temp.renameTo(target);
		}
	}

	private String node2Str(Element element) {
		TransformerFactory transFactory = TransformerFactory.newInstance();
		Transformer transformer = null;
		try {
			transformer = transFactory.newTransformer();
		} catch (TransformerConfigurationException e) {
			e.printStackTrace();
		}
		StringWriter buffer = new StringWriter();
		transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
		try {
			transformer.transform(new DOMSource(element), new StreamResult(
					buffer));
		} catch (TransformerException e) {
			e.printStackTrace();
		}
		return buffer.toString();
	}
}
